package com.devin.aop;

import com.devin.controller.LogController;
import com.devin.controller.MyErrorController;
import com.devin.pojo.LogInfo;
import com.devin.service.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class LogAop {
    private Date visitTime;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private LogService logService;

    @Pointcut("execution(* com.devin.controller.*.*(..))")
    public void logPoint(){};

    @Before("logPoint()")
    public void logBefore(){
        visitTime = new Date();
    }
    @After("logPoint()")
    public void logAfter(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> aClass = joinPoint.getTarget().getClass();
        if(aClass==null || aClass == LogController.class ||aClass== MyErrorController.class){
            return;
        }

        LogInfo logInfo = new LogInfo();
        long duration = new Date().getTime() - visitTime.getTime();
        logInfo.setVisitTime(visitTime);    //访问时间
        logInfo.setDuration(duration);      //访问时长

        logInfo.setIp(request.getRemoteAddr());     /*ip地址*/

        //人物username，secruity中获得
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        if(authentication==null){
            return;  //用户没有未登录，不记录日志
        }else {
            User user =(User) authentication.getPrincipal();
            System.out.println(user);
            String username = user.getUsername();
            logInfo.setUsername(username);          //登陆成功的用户名
        }

        String methodName = joinPoint.getSignature().getName();//有参和无参方法重载，方法名称相同
        logInfo.setMethod(methodName);

        Object[] args = joinPoint.getArgs();
        Method method=null;
       if(args==null || args.length==0){
           method = aClass.getMethod(methodName);
       }else{
           Class[] classes = new Class[args.length];
           for(int i=0;i<args.length;i++){
               classes[i]=args[i].getClass();
           }
           method = aClass.getMethod(methodName, classes);
       }
        RequestMapping annotationMethod = method.getAnnotation(RequestMapping.class);
        RequestMapping annotationClass = aClass.getAnnotation(RequestMapping.class);
        if(annotationClass==null || annotationMethod==null){
            return;
        }
        String methodUrl = annotationMethod.value()[0];
        String classURl = annotationClass.value()[0];
        logInfo.setUrl(classURl+methodUrl);
        //logService.saveLog(logInfo);
    }

}
